package makabakaquestionnaire.zutsoftware.system.controller;

import makabakaquestionnaire.zutsoftware.annotation.Log;
import makabakaquestionnaire.zutsoftware.entity.Users;
import makabakaquestionnaire.zutsoftware.entity.page.TableDataInfo;
import makabakaquestionnaire.zutsoftware.enums.BusinessType;
import makabakaquestionnaire.zutsoftware.exception.job.TaskException;
import makabakaquestionnaire.zutsoftware.framework.Task.quartzt.entity.SysJob;
import makabakaquestionnaire.zutsoftware.framework.Task.quartzt.service.ISysJobService;
import makabakaquestionnaire.zutsoftware.framework.Task.quartzt.util.cron.TaskScheduleModel;
import makabakaquestionnaire.zutsoftware.framework.security.Service.TokenService;
import makabakaquestionnaire.zutsoftware.framework.security.model.LoginUser;
import makabakaquestionnaire.zutsoftware.system.common.AjaxResult;
import makabakaquestionnaire.zutsoftware.system.common.BaseController;
import makabakaquestionnaire.zutsoftware.system.entity.Course;
import makabakaquestionnaire.zutsoftware.system.entity.CourseUser;
import makabakaquestionnaire.zutsoftware.system.service.ICourseService;
import makabakaquestionnaire.zutsoftware.utils.ServletUtils;
import makabakaquestionnaire.zutsoftware.utils.String.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.List;

import static makabakaquestionnaire.zutsoftware.framework.Task.quartzt.util.cron.CronUtil.createCronExpression;


/**
 * 课程信息Controller
 *
 * @author wjf
 * @date 2022-03-13
 */
@RestController
@RequestMapping("/system/course")
public class CourseController extends BaseController {
    @Autowired
    private ICourseService courseService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private ISysJobService jobService;

    /**
     * 查询已选该课的课人员信息
     *
     * @param courseUser：即courseId
     * @return
     */
    @PostMapping("/usersList")
    public AjaxResult selectUsersList(@RequestBody CourseUser courseUser) {
        List<Users> users = courseService.selectUsersList(courseUser);
        return AjaxResult.success(users);
    }

    /**
     * 查询用户的选课信息
     * 参数为在线用户的id
     */
    @GetMapping("/selectedCourses")
    public AjaxResult selectedCoursesList() {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Long userId = loginUser.getUser().getId();
        CourseUser courseUser = new CourseUser();
        courseUser.setUserId(userId);
        List<Course> courseList = courseService.selectedCoursesList(courseUser);
        return AjaxResult.success(courseList);
    }

    /**
     * 查询课程信息列表
     */
    @PreAuthorize("@ss.hasPermi('system:course:list')")
    @GetMapping("/list")
    public TableDataInfo list(Course course) {
        startPage();
        List<Course> list = courseService.selectCourseList(course);
        return getDataTable(list);
    }

    /**
     * 导出课程信息列表
     */
//    @PreAuthorize("@ss.hasPermi('system:course:export')")
//    @Log(title = "课程信息", businessType = BusinessType.EXPORT)
//    @GetMapping("/export")
//    public AjaxResult export(Course course)
//    {
//        List<Course> list = courseService.selectCourseList(course);
//        ExcelUtil<Course> util = new ExcelUtil<Course>(Course.class);
//        return util.exportExcel(list, "course");
//    }


    /**
     * 课程信息导入
     */
    @PostMapping("/importCourse")
    public AjaxResult importCourse(MultipartFile file) {
        int successNums = 0;
        try {
            Workbook workbook = WorkbookFactory.create(file.getInputStream());
            int numberOfSheets = workbook.getNumberOfSheets();
            for (int i = 0; i < numberOfSheets; i++) {
                Sheet sheet = workbook.getSheetAt(i);
                int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();
                for (int j = 1; j < physicalNumberOfRows; j++) {  //第一行为标题，不是数据
                    Row row = sheet.getRow(j);
                    if (row == null) {
                        continue;
                    }
                    int physicalNumberOfCells = row.getPhysicalNumberOfCells();
                    //设置Course的各个属性
                    Course course = new Course();
                    for (int k = 0; k < physicalNumberOfCells; k++) {
                        String cellValue = this.getCellValue(row, k).toString();
                        switch (k) {
                            case 0:
                                course.setCourseId(Long.parseLong(cellValue));
                                break;
                            case 1:
                                course.setCourseNo(Long.parseLong(cellValue));
                                break;
                            case 2:
                                course.setCourseName(cellValue);
                                break;
                            case 3:
                                course.setCoursePeriod(Long.parseLong(cellValue));
                                break;
                            case 4:
                                course.setCourseScore(Long.parseLong(cellValue));
                                break;
                            case 5:
                                course.setCourseIntroduce(cellValue);
                                break;
                            case 6:
                                course.setCourseTime(cellValue);
                                break;
                            case 7:
                                course.setCourseData(cellValue);
                            default:
                                break;
                        }
                    }
                    String cronExpression = getCronExpression(course.getCourseTime());
                    course.setCronExpression(cronExpression);
                    cronInsert(cronExpression, course);
                    courseService.insertCourse(course);
                    successNums++;
                }
            }
        } catch (IOException | TaskException | SchedulerException e) {
            e.printStackTrace();
        }
        return AjaxResult.success("共成功导入课程" + successNums + "节");
    }
    /**
     * 获取单元格值
     *
     * @param row 获取的行
     * @param column 获取单元格列号
     * @return 单元格值
     */
    public Object getCellValue(Row row, int column)
    {
        if (row == null)
        {
            return row;
        }
        Object val = "";
        try
        {
            Cell cell = row.getCell(column);
            if (StringUtils.isNotNull(cell))
            {
                if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA)
                {
                    val = cell.getNumericCellValue();
                    if (DateUtil.isCellDateFormatted(cell))
                    {
                        val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换
                    }
                    else
                    {
                        if ((Double) val % 1 != 0)
                        {
                            val = new BigDecimal(val.toString());
                        }
                        else
                        {
                            val = new DecimalFormat("0").format(val);
                        }
                    }
                }
                else if (cell.getCellType() == CellType.STRING)
                {
                    val = cell.getStringCellValue();
                }
                else if (cell.getCellType() == CellType.BOOLEAN)
                {
                    val = cell.getBooleanCellValue();
                }
                else if (cell.getCellType() == CellType.ERROR)
                {
                    val = cell.getErrorCellValue();
                }

            }
        }
        catch (Exception e)
        {
            return val;
        }
        return val;
    }


    /**
     * 获取课程信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:course:query')")
    @GetMapping(value = "/{courseId}")
    public AjaxResult getInfo(@PathVariable("courseId") Long courseId) {
        return AjaxResult.success(courseService.selectCourseById(courseId));
    }

    /**
     * 新增课程信息
     */
    @PreAuthorize("@ss.hasPermi('system:course:add')")
    @Log(title = "课程信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Course course) throws TaskException, SchedulerException {
        String cronExpression = getCronExpression(course.getCourseTime());
        course.setCronExpression(cronExpression);
        cronInsert(cronExpression, course);
        return toAjax(courseService.insertCourse(course));
    }

    /**
     * 根据上课时间生成cron
     *
     * @param cronExpression
     * @param course
     */
    public void cronInsert(String cronExpression, Course course) throws TaskException, SchedulerException {

        if (cronExpression != "" || StringUtils.isNotEmpty(cronExpression)) {
            String[] crons = cronExpression.split(";");
            for (String cron : crons) {
                SysJob sysJob = new SysJob();
                sysJob.setCourseId(course.getCourseId());
                sysJob.setCronExpression(cron);
                sysJob.setInvokeTarget("MessagePush.pushEmail");
                sysJob.setStatus(course.getStatus());
                sysJob.setMisfirePolicy("3");   //设置任务失败不继续执行
                sysJob.setStatus("1");    //默认不开启
                jobService.insertJob(sysJob);
            }
        }
    }

    /**
     * 修改课程信息
     */
    @PreAuthorize("@ss.hasPermi('system:course:edit')")
    @Log(title = "课程信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Course course) throws TaskException, SchedulerException {
        SysJob sysJob = new SysJob();
        sysJob.setCourseId(course.getCourseId());
        List<SysJob> sysJobs = jobService.selectJobList(sysJob);
        course.setCourseTime("");//默认更改状态时不更改上课时间
        if (StringUtils.isEmpty(course.getCourseTime()) || course.getCourseTime() == "") { //未更改上课时间
            for (SysJob job : sysJobs) {
                job.setStatus(course.getStatus());
                jobService.updateJob(job);
            }
        } else {
            for (SysJob job : sysJobs) {              //上课时间更改，删除原有的定时任务，重新创建
                jobService.deleteJob(job);
            }
            String cronExpression = getCronExpression(course.getCourseTime());
            course.setCronExpression(cronExpression);
            cronInsert(cronExpression, course);
        }
        return toAjax(courseService.updateCourse(course));
    }

    /**
     * 删除课程信息
     */
    @PreAuthorize("@ss.hasPermi('system:course:remove')")
    @Log(title = "课程信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{courseIds}")
    public AjaxResult remove(@PathVariable Long[] courseIds) {
        return toAjax(courseService.deleteCourseByIds(courseIds));
    }

    /**
     * 上课时间->cron表达式
     *
     * @param CourseTime
     * @return CronExpression
     */
    public String getCronExpression(String CourseTime) {
        String cronExpression = "";
        if (CourseTime == null || CourseTime == "") {
            return cronExpression;
        }
        String[] courseTimes = CourseTime.split(";");
        for (String courseTime : courseTimes) {
            Integer hour = Integer.parseInt(courseTime.substring(9, 11));
            Integer minute = Integer.parseInt(courseTime.substring(12, 14));
            Integer second = Integer.parseInt(courseTime.substring(15, 17));
            String Str = courseTime.substring(17, 20);
            Integer week;
            switch (Str) {
                case "星期一":
                    week = 2;
                    break;
                case "星期二":
                    week = 3;
                    break;
                case "星期三":
                    week = 4;
                    break;
                case "星期四":
                    week = 5;
                    break;
                case "星期五":
                    week = 6;
                    break;
                case "星期六":
                    week = 7;
                    break;
                case "星期日":
                    week = 1;
                    break;
                default:
                    week = 0;
                    break;
            }
            Integer[] weekDay = new Integer[]{week};
            TaskScheduleModel taskScheduleModel = new TaskScheduleModel();
            taskScheduleModel.setJobType(4);//按每分钟
            taskScheduleModel.setHour(hour);
            taskScheduleModel.setMinute(minute);
            taskScheduleModel.setSecond(second);
            taskScheduleModel.setJobType(3);//每周的哪几天执行
            taskScheduleModel.setDayOfWeeks(weekDay);
            cronExpression += createCronExpression(taskScheduleModel) + ";";
        }
        return cronExpression;
    }
}
